package com.qmock.pay.security;


import com.qmock.pay.common.ConfigParse;
import com.qmock.pay.common.UmpayConstValue;
import com.qmock.pay.exception.SignEncException;

import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


/**
 * 签名解密类
 */
public class UmpayRSA {

    private Cipher cipher	= null;
    private Signature				sig			= null;
    private X509Certificate	cert		= null;
    private UmpayRSA(){}

    public static UmpayRSA getInstance(String crtPath,String signP8Path) throws Exception{
        UmpayRSA umpayRSA=new UmpayRSA();
        umpayRSA.init(crtPath,signP8Path);
        return umpayRSA;
    }

    public static UmpayRSA getInstance(){
        UmpayRSA umpayRSA = new UmpayRSA();
        try {
            umpayRSA.init(ConfigParse.getPublicKeyPath(),ConfigParse.getPrivateKeyPath());
        } catch (Exception e) {
            throw new RuntimeException("签名的时候出现了错误",e);
        }
        return umpayRSA;
    }
    public void init(String crtpath,String signP8Path) throws Exception{
        byte[] certFile = new byte[20480];
        InputStream in_cert =null;
        InputStream in_p8=null;
        try{
            in_cert=new FileInputStream(new File(crtpath));
            ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(certFile);
            in_cert.read(certFile);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            cert = (X509Certificate) cf.generateCertificate(byteArrayInputStream);
            byte[] keyBytes = cert.getPublicKey().getEncoded();
            X509EncodedKeySpec x509EncodedKeySpec=new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey=keyFactory.generatePublic(x509EncodedKeySpec);
            cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);

            //加载.p8证书
            in_p8 = new FileInputStream(new File(signP8Path));
            byte[] b = new byte[20480];
            in_p8.read(b);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(b);
            KeyFactory keyFactory1=KeyFactory.getInstance("RSA");
            PrivateKey privateKey=keyFactory1.generatePrivate(pkcs8EncodedKeySpec);
            sig = Signature.getInstance("SHA1withRSA");
            sig.initSign(privateKey);
        }catch (Exception e){
            throw new RuntimeException("没有找到证书文件，请检查目录配置是否正确");
        }finally{
            in_cert.close();
            in_p8.close();
        }
    }
    /**生成签名
     * @param dataString 代签名的字符串
     * @return 签名之后的字符串
     * */
    public  String sign(String dataString) throws  SignEncException{
        try {
            sig.update(dataString.getBytes("utf-8"));
            byte[] signData = sig.sign();
            String signString = new String(Base64.encode(signData)).replace("\n","");
            return signString;
        } catch (Exception e) {
            throw new RuntimeException("签名的时候出现了错误，请检查程序");
        }

    }
 //    public static String sign(String dataString) throws SignEncException {
//        PrivateKey privateKey = getPrivateKey();
//        try {
//            Signature signature=Signature.getInstance("SHA1withRSA");
//            signature.initSign(privateKey);
//            signature.update(dataString.getBytes("utf-8"));
//            String signString = new String(Base64.encode(signature.sign())).replace("\n","");
//            return signString;
//        } catch (NoSuchAlgorithmException e) {
//            throw new SignEncException("签名失败！",e);
//        } catch (InvalidKeyException e) {
//            throw new SignEncException("签名失败！",e);
//        } catch (SignatureException e) {
//            throw new SignEncException("签名失败！",e);
//        } catch (UnsupportedEncodingException e) {
//            throw new SignEncException("签名失败！",e);
//        }
//    }

    /***
     * @param dataString 代签名的字符串
     * @param  signString 未签名的字符串
     * @return false标识签名失败 true表示签名成功
     * @exception SignEncException
     */
    public boolean verify(String dataString, String signString) throws SignEncException{
        try{
            byte[] signed = Base64.decode(signString);
            Signature signature = Signature.getInstance("SHA1WithRSA");
            signature.initVerify(cert);
            signature.update(dataString.getBytes("GBK"));
            if(signature==null){
                System.out.println("signature为空");
            }
            return signature.verify(signed);
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return false;
    }

    /**
     * 取得文件路径
     * */
    private String getPath(String path,String fileName){
        String basepath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(basepath);
        stringBuilder.append(path);
        stringBuilder.append(fileName);
        return stringBuilder.toString();
    }

 }
